package sk.datalan.sparqlreasoner;

import java.util.List;

import org.openrdf.query.QueryLanguage;
import org.openrdf.query.Update;
import org.openrdf.repository.RepositoryConnection;

import sk.datalan.core.DatabaseManager;
import sk.datalan.core.Utils;

public class Rule implements Runnable {
	private String query;
	private String id;
	private List<String> dependsOn;
	private static QueryLanguage qLang;
	private boolean isExecuting = false;
	private boolean isComplete = false;

	public Rule( String id, String query, List<String> dependsOn ) {
		this( id, query, dependsOn, QueryLanguage.SPARQL );
	}

	public Rule( String id, String query, List<String> dependsOn, QueryLanguage qLang ) {
		setId( id );
		setQuery( query );
		setDependsOn( dependsOn );
		setqLang( qLang );
	}

	public String getQuery() {
		return query;
	}

	public void setQuery( String query ) {
		this.query = query;
	}

	public String getId() {
		return id;
	}

	public void setId( String id ) {
		this.id = id;
	}

	public List<String> getDependsOn() {
		return dependsOn;
	}

	public void setDependsOn( List<String> dependsOn ) {
		this.dependsOn = dependsOn;
	}

	@Override
	public void run() {
		executeSingleQuery( getQuery() );
		this.setComplete( true );
		this.setIsExecuting( false );

	}

	public boolean isExecuting() {
		return isExecuting;
	}

	public boolean setIsExecuting( boolean isExecuting ) {
		return this.isExecuting = isExecuting;
	}

	public boolean isReady( List<Rule> rules ) {
		int count = 0;

		if ( count == getDependsOn().size() ) {
			return true;
		}

		for ( Rule rule : rules ) {
			for ( String d : getDependsOn() ) {
				if ( rule.getId().equals( d ) && rule.isComplete() ) {
					count++;
				}
			}
		}

		if ( count == getDependsOn().size() ) {
			return true;
		}
		return false;
	}

	private void executeSingleQuery( String query ) {
		try {
			RepositoryConnection con = DatabaseManager.getInstance().getRepository().getConnection();

			// long queryBegin = System.currentTimeMillis();
			Update updateQuery = con.prepareUpdate( getqLang(), query );
			
			updateQuery.execute();
			con.close();

		} catch ( Throwable e ) {
			Utils.log( "An error occurred during query execution: " + e.getMessage() );
		}
	}

	public boolean isComplete() {
		return isComplete;
	}

	private void setComplete( boolean isComplete ) {
		this.isComplete = isComplete;
	}

	public static QueryLanguage getqLang() {
		return qLang;
	}

	public static void setqLang( QueryLanguage qLang ) {
		Rule.qLang = qLang;
	}

}
